package org.example.shiro.config;

import at.pollux.thymeleaf.shiro.dialect.ShiroDialect;
import net.sf.ehcache.CacheManager;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;

import org.apache.shiro.cache.ehcache.EhCacheManager;
import org.apache.shiro.codec.Base64;
import org.apache.shiro.io.ResourceUtils;
import org.apache.shiro.spring.web.config.DefaultShiroFilterChainDefinition;
import org.apache.shiro.web.mgt.CookieRememberMeManager;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.apache.shiro.web.servlet.SimpleCookie;
import org.example.shiro.realm.CustomerRealm;
import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.io.IOException;
import java.io.InputStream;


/**
 * @author sky
 * @date 2025年03月25日 17:01
 * @description
 */
@Configuration
public class ShiroConfig{
    @Autowired
    private CustomerRealm customerRealm;

    //配置 SecurityManager
    @Bean
    public DefaultWebSecurityManager defaultWebSecurityManager() {
        //1.创建defaultWebSecurityManager对象
        DefaultWebSecurityManager defaultWebSecurityManager = new DefaultWebSecurityManager();
        //2.创建加密对象,并设置相关属性
        HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher();
        // 2.1 采用md5加密
        hashedCredentialsMatcher.setHashAlgorithmName("MD5");
        // 2.2 迭代加密次数
        hashedCredentialsMatcher.setHashIterations(1024);
        //3.将加密对象存储到CustomerRealm中
        customerRealm.setCredentialsMatcher(hashedCredentialsMatcher);
        //4.将CustomerRealm存储到defaultWebSecurityManager中
        defaultWebSecurityManager.setRealm(customerRealm);
        //4.1 设置RememberMe
        defaultWebSecurityManager.setRememberMeManager(rememberMeManager());
        //5.设置缓存管理器
        defaultWebSecurityManager.setCacheManager(getCacheManager());
        //6.返回
        return defaultWebSecurityManager;
    }

    /**
     * cookie属性设置
     */
    public SimpleCookie rememberMeCookie() {
        SimpleCookie cookie = new SimpleCookie("rememberMe");
        // 设置跨域
        //cookie.setDomain(domain);
        cookie.setPath("/");
        cookie.setHttpOnly(true);
        // 设置cookie的过期时间，单位为秒，这里设为30天
        cookie.setMaxAge(30 * 24 * 60 * 60);
        return cookie;
    }
    /**
     * 创建 Shiro 的 cookie 管理对象
     */
    public CookieRememberMeManager rememberMeManager() {
        CookieRememberMeManager cookieRememberMeManager = new CookieRememberMeManager();
        cookieRememberMeManager.setCookie(rememberMeCookie());
        //cookieRememberMeManager.setCipherKey("1234567890987654".getBytes());
        //设置加密密钥
        cookieRememberMeManager.setCipherKey(Base64.decode("4AvVhmFLUs0KTA3Kprsdag=="));
        return cookieRememberMeManager;
    }

    /**
     * 配置 Shiro 内置过滤器拦截范围
     */
    @Bean
    public DefaultShiroFilterChainDefinition defaultShiroFilterChainDefinition() {
        DefaultShiroFilterChainDefinition chainDefinition = new DefaultShiroFilterChainDefinition();
        // 配置过滤规则
        chainDefinition.addPathDefinition("/login", "anon");
        chainDefinition.addPathDefinition("/logout", "anon");
        chainDefinition.addPathDefinition("/register", "anon");
        chainDefinition.addPathDefinition("/css/**", "anon");
        chainDefinition.addPathDefinition("/js/**", "anon");
        chainDefinition.addPathDefinition("/img/**", "anon");
        //1.设置不需要拦截的路径
        chainDefinition.addPathDefinition("/LoginController/userLogin","anon");
        chainDefinition.addPathDefinition("/LoginController/login","anon");
        //2.设置拦截所有路径
        chainDefinition.addPathDefinition("/**","authc");
        //添加RememberMe存在用户的过滤器
        chainDefinition.addPathDefinition("/**","user");
        //2.2 配置登出过滤器
        chainDefinition.addPathDefinition("/logout","logout");
        //3.返回
        return chainDefinition;
    }

    /**
     * 用于解析thymeleaf中的  shiro:相关属性
     */
    @Bean
    public ShiroDialect shiroDialect() {
        return new ShiroDialect();
    }
    /**
     * 缓存管理器
     */
    public EhCacheManager getCacheManager() {
        EhCacheManager ehCacheManager = new EhCacheManager();
        InputStream is = null;

        try {
            is = ResourceUtils.getInputStreamForPath("classpath:ehcache/ehcache-shiro.xml");
        } catch (IOException e) {
            e.printStackTrace();
        }
        CacheManager cacheManager = new CacheManager(is);
        ehCacheManager.setCacheManager(cacheManager);
        return ehCacheManager;
    }
}
